/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cocma;

import java.util.BitSet;
import java.util.Comparator;
import schedulingScheme.CoverageMatrix;

/**
 *
 * @author Andrzej
 */
public class FitnessValue implements Comparator<Chromosome> {

    private CoverageMatrix coverageVector;

    public FitnessValue(CoverageMatrix coverageVector) {
        this.coverageVector = coverageVector;
    }



    private double sum(BitSet b) {
        int sum = 0;
        for (int i = 0; i < b.length(); i++) {
            if (b.get(i)) {
                sum++;
            }
        }
        return sum;
    }
    private double sum(Chromosome b) {
        int sum = 0;
        for (int i = 0; i < b.length(); i++) {
            if (b.getAllele(i)) {
                sum++;
            }
        }
        return sum;
    }

    public double fitnessValue(Chromosome chromosome) {
        double alfa1 = 1, alfa2 = 1;
        double lambda1 = 2, lambda2 = 0.5;
        double result;
//        assert (chromosome.length == coverageVector.length);

        BitSet coveredPOIs = new BitSet();
        for (int i = 0; i < chromosome.length(); i++) {
            if (chromosome.getAllele(i)) {
                BitSet coverageOfSensor = coverageVector.coverageOfSensor(i);
                coveredPOIs.or(coverageOfSensor);
            }
        }
//        result = alfa1 * Math.pow(sum(coveredPOIs) / coveredPOIs.length(), lambda1) - alfa2 * Math.pow(sum(chromosome) / chromosome.length(), lambda2);
        //TODO czy na pewno ok, jest późno 00:40
        double coverage = alfa1 * Math.pow(((double) coveredPOIs.cardinality()) / chromosome.length(), lambda1);
        double energy = alfa2 * Math.pow(((double) sum(chromosome) )/ chromosome.length(), lambda2);
        result = coverage - energy;
        return result;
    }

    @Override
    public int compare(Chromosome o1, Chromosome o2) {
        return new Double(fitnessValue(o1)).compareTo(fitnessValue(o2));
    }

}
